{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 误差分析\n",
    "\n",
    "\n",
    "*版权所有 (c) 2021 百度量子计算研究所，保留所有权利。*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 内容概要\n",
    "\n",
    "本教程将以 Cross Resonance（CR）门为例，演示如何分析实际量子门操作的误差。我们将使用动力学演化分析、真值表（Truth Table）等工具可视化非计算空间的能级泄露等相关信息。本教程的大纲如下：\n",
    "\n",
    "- 背景介绍\n",
    "- 准备工作\n",
    "- 构造哈密顿量并优化脉冲\n",
    "- 动力学分析\n",
    "- 真值表\n",
    "- 总结"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 背景介绍\n",
    "\n",
    "使用控制脉冲实现目标量子门时，实际的量子操作可能与目标操作不同。两者之间差异通常被量化为失真度。分析造成误差的来源，对我们提高量子门的保真度至关重要。\n",
    "\n",
    "量脉提供了通过动力学分析来探究量子比特状态总体演化的功能，并通过真值表可视化计算空间外的能级泄露。在本教程中，我们将以 Cross Resonance（CR）量子门为例进行演示。有关 CR 门的更多详细信息，请参见 [Cross Resonance 量子门](https://quanlse.baidu.com/#/doc/tutorial-cr) 教程。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备工作\n",
    "\n",
    "在设备上成功安装量脉后，您可以按照本教程运行下面的量脉的程序。要运行此教程，您需要从量脉（Quanlse）和其它常用的 Python 库导入以下包："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This module is imported for creating Hamiltonian dictionary\n",
    "from Quanlse.QHamiltonian import QHamiltonian as QHam\n",
    "\n",
    "# These functions are imported to define useful operators matrices to free us from defining them manually\n",
    "from Quanlse.QOperator import number, duff, dagger, driveX, driveY\n",
    "\n",
    "# These functions are imported to helps us perform matrix calculation\n",
    "from Quanlse.Utils.Functions import tensor, project, basis, tensor, projector\n",
    "\n",
    "# This function is imported to perform CR gate optimization using Quanlse Cloud Service\n",
    "from Quanlse.remoteOptimizer import remoteOptimizeCr\n",
    "\n",
    "# This module is imported to define frequently-used matrix form for quantum gates\n",
    "from Quanlse.QOperation import FixedGate\n",
    "\n",
    "# This module is imported to perform figure plotting\n",
    "from Quanlse.Utils import Plot\n",
    "\n",
    "# Import the necessary packages\n",
    "import numpy\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在使用 `remoteOptimizeCr()` 函数访问云服务之前，我们需要从[百度量易伏](https://quantum-hub.baidu.com)官网上申请一个 token。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import Define class and set the token\n",
    "# Please visit http://quantum-hub.baidu.com\n",
    "from Quanlse import Define\n",
    "Define.hubToken = \"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造哈密顿量并优化脉冲\n",
    "我们首先使用以下代码构造系统哈密顿量，并优化控制参数以实现高保真度的 CR 门："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define parameters to initialize the Hamiltonian\n",
    "dt = 2.0  # Sampling period\n",
    "qubits = 2  # Number of qubits\n",
    "level = 3  # Energy level\n",
    "\n",
    "# Define qubit parameters\n",
    "g = 0.0038 * (2 * numpy.pi)  # Coupling strength, GHz\n",
    "wq0  = 4.914 * (2 * numpy.pi)  # Transition frequency for qubit 0, GHz\n",
    "wq1 = 4.714 * (2 * numpy.pi)  # Transition frequency for qubit 1, GHz\n",
    "wd1 = wq1  # Drive frequency is the frequency for qubit 1\n",
    "anharm0 = - 0.33 * (2 * numpy.pi)  # Anharmonicity of qubit 0, GHz\n",
    "anharm1 = - 0.33 * (2 * numpy.pi)  # Anharmonicity of qubit 1, GHz\n",
    "\n",
    "# Initialize the Hamiltonian\n",
    "ham = QHam(subSysNum=qubits, sysLevel=level, dt=dt)\n",
    "\n",
    "# Add the detuning terms\n",
    "ham.addDrift(number, onSubSys=0, coef=wq0 - wd1)\n",
    "ham.addDrift(number, onSubSys=1, coef=wq1 - wd1)\n",
    "\n",
    "# Add the anharmonicity terms\n",
    "ham.addDrift(duff, onSubSys=0, coef=anharm0 / 2)\n",
    "ham.addDrift(duff, onSubSys=1, coef=anharm0 / 2)\n",
    "\n",
    "# Add the coupling term\n",
    "ham.addCoupling([0, 1], g=g / 2)\n",
    "\n",
    "# Set amplitude bound\n",
    "aBound = (1.0, 3.0)\n",
    "\n",
    "# Run the optimization on Quanlse Cloud Service\n",
    "job, infidelity = remoteOptimizeCr(ham, aBound=aBound, tg=200, maxIter=3, targetInfidelity=0.01)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 动力学分析\n",
    "\n",
    "研究量子操作过程中初始量子态的演化有助于我们理解控制脉冲对量子比特状态的影响。而量脉中的动力学分析功能可模拟给定初始状态下不同量子比特状态的演化。\n",
    "\n",
    "在下面的示例中，我们将演示当初始量子比特状态为 $|01\\rangle$ 时，执行 CR 门的过程中两比特计算空间内四个正交基（ $|00\\rangle$，$|01\\rangle$，$|10\\rangle$ 和 $|11\\rangle$）的演化过程。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，我们使用 `basis()` 函数为两比特系统定义完整的计算空间内的正交基，该函数的第一个输入是能级数（例如：三能级系统为 3），第二个输入是量子态（在这个示例中为 0 或 1 ）。然后，我们使用 `tensor()` 函数构造这两个量子比特的态矢量。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define basis states: 00, 01, 10 and 11\n",
    "state00 = tensor(basis(3, 0), basis(3, 0))\n",
    "state01 = tensor(basis(3, 0), basis(3, 1))\n",
    "state10 = tensor(basis(3, 1), basis(3, 0))\n",
    "state11 = tensor(basis(3, 1), basis(3, 1))\n",
    "stateList = [state00, state01, state10, state11]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "随后，我们构造四个正交基所对应的投影矩阵，并根据这四个投影矩阵的期望值来分别计算每个正交基上的观测结果。我们使用 `projector()` 函数创建投影矩阵。`projector(a, b)` 的输入为两个先前定义的量子态向量（$|a\\rangle$ 和 $|b\\rangle$）并生成投影矩阵 $|a\\rangle \\langle b|$。如果仅将一个量子态向量作为输入，例如 $|a\\rangle$，则此函数将返回 $|a\\rangle \\langle a|$。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Construct projection matrices from basis states\n",
    "matrix00 = projector(state00)\n",
    "matrix01 = projector(state01)\n",
    "matrix10 = projector(state10)\n",
    "matrix11 = projector(state11)\n",
    "matrixList = [matrix00, matrix01, matrix10, matrix11]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们使用 `Benchmark.evolution()` 函数来计算 CR 门操作过程中每个投影矩阵的期望值的变化过程。该函数需要三个输入参数：系统哈密顿量，初始态矢量列表和投影矩阵的列表。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run the simulation to evaluate evolution of the expectation values\n",
    "from Quanlse.Utils import Benchmark\n",
    "ham.job = job\n",
    "evolutionResult = Benchmark.evolution(ham, stateInitial=stateList, matrix=matrixList)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "该函数的返回**结果**是一个 Python 字典。键 `0`，`1`，`2` … 指的是初始量子态的索引。该 Python 字典的每一个索引，都对应一个子 Python 字典，其键值包括：\n",
    "\n",
    "* `state_form`：初始态矢量\n",
    "* `state_evolution_history`：初始态矢量的演化过程详细数据\n",
    "* `result`：不同投影矩阵期望值的演化数据。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "现在，我们可以通过获取**不同基态**在**不同时刻**的期望值来绘制量子态演化的图像。在下面的部分中，我们将初始态定义为 $|01\\rangle$，并计算概率与时间的演化关系。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Define x values to be the time for evolution\n",
    "endTimeNs, endTimeDt = ham.job.computeMaxTime()\n",
    "x = numpy.linspace(0, endTimeNs, endTimeDt)\n",
    "\n",
    "# Define y values to be the expectation value for each projection matrix when the initial state is in 01, which corresponds to index 1\n",
    "y1 = numpy.array(evolutionResult['1']['result']['matrix-0-value'])\n",
    "y2 = numpy.array(evolutionResult['1']['result']['matrix-1-value'])\n",
    "y3 = numpy.array(evolutionResult['1']['result']['matrix-2-value'])\n",
    "y4 = numpy.array(evolutionResult['1']['result']['matrix-3-value'])\n",
    "\n",
    "# Plot the population as absolute value of the expectation values\n",
    "plt.plot(x, abs(y1), linewidth=3, label='00')\n",
    "plt.plot(x, abs(y2), linewidth=3, label='01')\n",
    "plt.plot(x, abs(y3), linewidth=3, label='10')\n",
    "plt.plot(x, abs(y4), linewidth=3, label='11')\n",
    "plt.title(r'Population Evolution for $|01\\rangle$ Initial State ')\n",
    "plt.xlabel('Time (ns)')\n",
    "plt.ylabel('Population')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 真值表（Truth table）\n",
    "\n",
    "量子门的真值表表示的是，不同的基态作为初始态在量子操作结束时处于不同基态的概率。在这里，我们从计算空间内选择初始态，而最终状态则可以处于计算空间之外，计算空间之外的末态即对应能级泄露。量脉提供了为量子过程计算真值表并使用热力图可视化结果的功能。它可以帮助我们分析能级泄露所带来的误差。\n",
    "\n",
    "这里，我们将通过分析*构造哈密顿量并优化脉冲*章节生成的 CR 门的酉算符来介绍这个工具。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import the function for generating the truth table\n",
    "from Quanlse.Utils.Benchmark import stateTruthTable\n",
    "\n",
    "# Import the function for plotting the heat map\n",
    "from Quanlse.Utils.Plot import plotHeatMap\n",
    "\n",
    "# Import the functions for basis operations\n",
    "from Quanlse.Utils.Functions import generateBasisIndexList, computationalBasisList\n",
    "\n",
    "# Indicate the input state list, and generate the list of the state indices\n",
    "inputStateStr = ['00', '01', '10', '11']\n",
    "initStateList = generateBasisIndexList(inputStateStr, level)\n",
    "\n",
    "# Generate the matrix of the truth table\n",
    "result = ham.simulate()\n",
    "matrix = stateTruthTable(result[0][\"unitary\"], qubits, level, initStateList)\n",
    "\n",
    "# Generate the list of the output state strings and plot the heat map\n",
    "outputStateStr = computationalBasisList(qubits, level)\n",
    "plotHeatMap(matrix, xTicks=outputStateStr, yTicks=inputStateStr, xLabel=\"Output State\", yLabel=\"Input State\", useLog=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过上面的热力图，我们可以直观地读出演化以及能级泄露的信息。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 总结\n",
    "\n",
    "本教程介绍了量脉的误差分析功能。其中，动力学分析为我们提供了量子态演化的完整图像，而真值表则告诉我们不同初始状态下误差的分布。\n",
    "\n",
    "在阅读了本教程之后，用户可以单击此链接 [tutorial-error-analysis.ipynb](https://github.com/baidu/Quanlse/blob/main/Tutorial/CN/tutorial-error-analysis-cn.ipynb) 到该 Jupyter Notebook 文档的 GitHub 页面，并运行该程序。我们鼓励用户在不同场景应用本教程提供的工具和方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## 参考文献\n",
    "\n",
    "\\[1\\] [Nielsen, Michael A., and Isaac L. Chuang. Quantum Computation and Quantum Information: 10th Anniversary Edition. Cambridge University Press, 2010.](http://mmrc.amss.cas.cn/tlb/201702/W020170224608149940643.pdf)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
